package com.yzkj.siot.facade.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yzkj.siot.domain.AdminTenant;
import com.yzkj.siot.domain.TenantUser;
import com.yzkj.siot.exp.BizExp;
import com.yzkj.siot.facade.TenantFacade;
import com.yzkj.siot.result.PageParams;
import com.yzkj.siot.result.PageResponse;
import com.yzkj.siot.service.AdminTenantService;
import com.yzkj.siot.service.TenantUserService;
import com.yzkj.siot.util.PageHelper;
import com.yzkj.siot.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;

@Service
public class TenantFacadeImpl implements TenantFacade {

    @Autowired
    AdminTenantService adminTenantService;

    @Autowired
    PageHelper<AdminTenant> tenantPageHelper;

    @Autowired
    TenantUserService tenantUserService;

    @Autowired
    RedisUtil redisUtil;

    @Override
    public PageResponse<AdminTenant> page(PageParams<AdminTenant> pageParams) {

        AdminTenant where = pageParams.getEntity();

        // 构造queryWrapper
        QueryWrapper<AdminTenant> tenantQueryWrapper = new QueryWrapper<>();

        if (where != null) {
            tenantQueryWrapper.lambda()
                    .eq(where.getStatus() != null, AdminTenant::getStatus, where.getStatus())
                    .like(!StringUtils.isEmpty(where.getTenantAlias()), AdminTenant::getTenantAlias,
                            where.getTenantAlias())
                    .like(!StringUtils.isEmpty(where.getTenantName()), AdminTenant::getTenantName,
                            where.getTenantName());
        }

        pageParams.getOrderBy().forEach(item -> tenantQueryWrapper.orderBy(true, item.getIsAsc(), item.getField()));

        return tenantPageHelper.queryPageOrList(adminTenantService.getBaseMapper(), pageParams, tenantQueryWrapper);
    }

    @Override
    public AdminTenant queryOne(int id) {
        return adminTenantService.getById(id);
    }

    @Transactional
    @Override
    public AdminTenant saveOrUpdate(AdminTenant entity) {

        // 校验alias唯一
        QueryWrapper<AdminTenant> adminTenantQueryWrapper = new QueryWrapper<>();
        adminTenantQueryWrapper.lambda().eq(AdminTenant::getTenantAlias, entity.getTenantAlias());

        if (entity.getId() != null && entity.getId() != 0) {
            adminTenantQueryWrapper.lambda().ne(AdminTenant::getId, entity.getId());
        }

        if (adminTenantService.count(adminTenantQueryWrapper) != 0) {
            throw new BizExp("租户唯一标识重复！");
        }

        if (entity.getId() == null || entity.getId() == 0) {
            return save(entity);
        }
        return update(entity);
    }

    private AdminTenant save(AdminTenant entity) {
        // 构建密码
        entity.setTenantPwd(entity.getTenantAlias());
        adminTenantService.save(entity);
        // create first user
        createFirstUserOfTenant(entity);
        // create enable cache
        redisUtil.sSet("tenant_enable", entity.getId());
        return queryOne(entity.getId());
    }

    private AdminTenant update(AdminTenant entity) {
        // id != 0 && entity.status != null => update status
        if (entity.getId() != null && entity.getStatus() != null) {
            updateRedisTenantEnable(entity.getId(), entity.getStatus());
        }

        adminTenantService.updateById(entity);
        return queryOne(entity.getId());
    }

    private void createFirstUserOfTenant(AdminTenant tenant) {
        // 创建0号用户
        TenantUser tenantUser = new TenantUser();
        tenantUser.setTenantId(tenant.getId());
        tenantUser.setUserName(tenant.getTenantAlias());
        tenantUser.setPassword(tenant.getTenantAlias());
        tenantUser.setUserEmail(tenant.getUserEmail());
        tenantUser.setRoleId(1);

        tenantUserService.saveOrUpdate(tenantUser);
    }

    private void updateRedisTenantEnable(Integer tenantId, Integer status) {
        // update tenant status need change redis cache
        if (status == 1) {
            redisUtil.sSet("tenant_enable", tenantId);
        }

        if (status == 2) {
            redisUtil.setRemove("tenant_enable", tenantId);
        }
    }

    @Override
    public AdminTenant remove(int id) {
        return null;
    }

    @Override
    public Boolean batchRemove(List<Integer> idList) {
        return null;
    }

    @Override
    public Boolean batchSave(List<AdminTenant> entities) {
        return null;
    }
}
